#ifndef EVENT_GROUPS_H
#define EVENT_GROUPS_H

#ifndef INC_FREERTOS_H
	#error "include FreeRTOS.h" must appear in source files before "include event_groups.h"
#endif

/* FreeRTOS includes. */
#include "timers.h"

#ifdef __cplusplus
extern "C" {
#endif

typedef void * EventGroupHandle_t;

typedef TickType_t EventBits_t;

/**
 * @brief 创建事件组
 * @return 事件组句柄
 */
#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
	EventGroupHandle_t xEventGroupCreate( void ) PRIVILEGED_FUNCTION;
#endif

/**
 * @brief 静态创建事件组
 * @param pxEventGroupBuffer 
 * @return 事件组句柄
 */
#if( configSUPPORT_STATIC_ALLOCATION == 1 )
	EventGroupHandle_t xEventGroupCreateStatic( StaticEventGroup_t *pxEventGroupBuffer ) PRIVILEGED_FUNCTION;
#endif

/**
 * @brief 用于得知"感兴趣"的事件
 * @param xEventGroup 事件句柄
 * @param uxBitsToWaitFor 设置的位
 * @param xClearOnExit pdTRUE表示满足时会清除由xWaitForAllBits设置的标志位，pdFALSE表示不会由形参xWaitForAllBits清除标志位
 * @param xWaitForAllBits paTRUE表示逻辑与，pdFALSE表示逻辑或
 * @param xTicksToWait T最大超时时间
 * @return 返回哪些位被置位，返回值很可能不是用户指定的事件位,需要对返回值进行处理
 */
EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToWaitFor, const BaseType_t xClearOnExit, const BaseType_t xWaitForAllBits, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;

/**
 * @brief 清除事件标志位
 * @param xEventGroup 事件组句柄
 * @param uxBitsToClear 要清除的标志位
 * @return 没有清除标志位之前的值
 */
EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear ) PRIVILEGED_FUNCTION;

/**
 * @brief 中断中清除事件标志位
 * @param xEventGroup 事件组句柄
 * @param uxBitsToClear 要清除的标志位
 * @return 没有清除标志位之前的值
 */
#if( configUSE_TRACE_FACILITY == 1 )
	BaseType_t xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet ) PRIVILEGED_FUNCTION;
#else
	#define xEventGroupClearBitsFromISR( xEventGroup, uxBitsToClear ) xTimerPendFunctionCallFromISR( vEventGroupClearBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToClear, NULL )
#endif

/**
 * @brief 置位事件中指定的位
 * @param xEventGroup 事件组句柄
 * @param uxBitsToSet 指定事件中的事件标志位
 * @return 调用该函数时事件组中的值
 */
EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet ) PRIVILEGED_FUNCTION;

/**
 * @brief 中断中置位事件组中指定的位
 * @param xEventGroup 事件句柄
 * @param uxBitsToSet 指定哪些位需要置位
 * @param pxHigherPriorityTaskWoken 
 * @return 成功pdPASS 失败pdFALSE
 */
#if( configUSE_TRACE_FACILITY == 1 )
	BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, BaseType_t *pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;
#else
	#define xEventGroupSetBitsFromISR( xEventGroup, uxBitsToSet, pxHigherPriorityTaskWoken ) xTimerPendFunctionCallFromISR( vEventGroupSetBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToSet, pxHigherPriorityTaskWoken )
#endif

/**
 * @brief 使用事件组彼此同步两个或多个任务的功能
 * @param xEventGroup 事件组的句柄。
 * @param uxBitsToSet 需要置位的位。
 * @param uxBitsToWaitFor 等待的位
 * @param xTicksToWait 阻塞等待的时间。
 * @return 若所有相关位均已置位，则返回的值为复位前的数据组的值，若超时则返回的值为阻塞等待的时间。
 */
EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, const EventBits_t uxBitsToWaitFor, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;


/**
 * @brief 获取事件标志
 * @param xEventGroup 事件句柄
 * @return 事件标志
 */
#define xEventGroupGetBits( xEventGroup ) xEventGroupClearBits( xEventGroup, 0 )

/**
 * @brief 中断中获取事件标志
 * @param xEventGroup 事件句柄
 * @return 事件标志
 */
EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup ) PRIVILEGED_FUNCTION;

/**
 * @brief 删除事件组
 * @param xEventGroup 事件组句柄
 */
void vEventGroupDelete( EventGroupHandle_t xEventGroup ) PRIVILEGED_FUNCTION;

/* For internal use only. */
void vEventGroupSetBitsCallback( void *pvEventGroup, const uint32_t ulBitsToSet ) PRIVILEGED_FUNCTION;
void vEventGroupClearBitsCallback( void *pvEventGroup, const uint32_t ulBitsToClear ) PRIVILEGED_FUNCTION;


#if (configUSE_TRACE_FACILITY == 1)
	UBaseType_t uxEventGroupGetNumber( void* xEventGroup ) PRIVILEGED_FUNCTION;
#endif

#ifdef __cplusplus
}
#endif

#endif /* EVENT_GROUPS_H */


